#include "utilities.hpp"
#include <string.h>
#include <cstring>

#include <iostream>
#include <fstream>    

#include <Wt/WApplication> // for loadStylesheet()
// using namespace std; // delete this


/*
 * Wrap WApplication::useStyleSheet() because if the file doesn't exist, Wt will just
 * continue and ignore the problem.
 */
void utilities::loadStylesheet(const char* filename)
{
    /*
     * Test opening the file and then close it - ensure the file exists and we have
     * read access to it.
     */
    std::string stylesheet(Wt::WApplication::instance()->docRoot().append(filename));
    
    std::ifstream file(stylesheet.c_str(), std::ifstream::in);
    
    if( !file.good() )
    {
        std::cerr << "********File can not be opened: " << stylesheet <<
        ". Please reinstall the software." << std::endl;
        throw; //TODO throw a proper exception. 
    }
    else file.close();

    // Finally, give the file name to Wt.
    Wt::WApplication::instance()->useStyleSheet(filename); 
}


utilities::SRootDirectory::SRootDirectory()
{
    char tmp[1024] = {'0'};
    ssize_t len = readlink("/proc/self/exe", tmp, sizeof(tmp)-1);
    if (len == -1) perror("readlink failed"); //BUG need to throw an exception here.
    else tmp[len] = '\0'; 
    
    m_path = tmp; 
    
    // Trim off the executable name plus the proceeding '/'.
    m_path.erase( m_path.find_last_of('/'));
}


utilities::ModifiedArgv::ModifiedArgv(int argc, char *argv[])
{
    bool docroot_found  = false;
    bool config_found   = false;
    
    m_argv  = nullptr;
    m_count     = argc;
    
    // Search for the items to be overridden.
    for (int i = 0; i < argc; i++)
    {
        /*
         * Allow user overrides.
         */
        std::string str(argv[i]);
        
        if (str.find("--docroot") != std::string::npos)
        {
            docroot_found = true;
            m_count++;
        }
        if (str.find("--config") != std::string::npos)
        {
            config_found = true;
            m_count++;
        }
        
        m_temp_storage.push_back(str);
    }
    
    
    if (docroot_found  == false)
    {        
        std::string str("--docroot=/usr/lib/carblogger_ui");
        
//         str.append(SRootDirectory::instance()->get_path());

        m_temp_storage.push_back(str);
    }
    if (config_found  == false)
    {        
        std::string str("--config=");
        
//         str.append(SRootDirectory::instance()->get_path());
        
        str.append("/etc/carblogger_ui-config.xml");
        
        m_temp_storage.push_back(str);
    }
}

/*
 * I could reuse/output argv to reduce one variable, but this is fine for now.
 */
char** utilities::ModifiedArgv::getArgs()
{
    m_argv = new char*[m_temp_storage.size()];
    
    for(unsigned i = 0; i < m_temp_storage.size(); ++i)
    {
        m_argv[i] = const_cast<char*>(m_temp_storage[i].c_str());            
    } 
    
    return m_argv;
}


/*
 * Allocating and initializing SRootDirectory's static data member.  The pointer is being
 * allocated - not the object itself. 
 */
utilities::SRootDirectory * utilities::SRootDirectory::s_instance = 0;

